#include "F3LampInterfaces.h"
#include <sstream>
#include <iostream>

Widget* g_Widget = NULL;

float getPosnBriSet()
{
    float value = 0;
    switch(Get_CANSIG_FLPosnLampBriSet())
    {
    case PosnLampBri_Night:
        value = PosnLampOutput_Night_MA/DaytimeLampOutput_MA*DaytimeLampPwm_MaxCurrent;//% 12ma
        break;

    case PosnLampBri_Daytime1:
        value = PosnLampOutput_DAY1_MA/DaytimeLampOutput_MA*DaytimeLampPwm_MaxCurrent;//% 28ma
        break;

    case PosnLampBri_Daytime2:
        value = PosnLampOutput_DAY2_MA/DaytimeLampOutput_MA*DaytimeLampPwm_MaxCurrent;//% 50ms
        break;

    default:
        value = PosnLampOutput_Night_MA/DaytimeLampOutput_MA*DaytimeLampPwm_MaxCurrent;//% 12ma
        break;
    }

    return value;
}

//188ma as 100%
float getStarrySkyBriSet()
{
    float value = 0;
    switch(Get_CANSIG_FLPosnLampBriSet())
    {
    case PosnLampBri_Initial:
        value = 0.0;
        break;

    case PosnLampBri_Night:
        value = StarrySkyLampOutput_Night_MA/DaytimeLampOutput_MA*StarrySkyLamp_MaxCurrent;//% 26ma
        break;

    case PosnLampBri_Daytime1:
        value = StarrySkyLampOutput_DAY1_MA/DaytimeLampOutput_MA*StarrySkyLamp_MaxCurrent;//% 52ma
        break;

    case PosnLampBri_Daytime2:
        value = StarrySkyLampOutput_DAY2_MA/DaytimeLampOutput_MA*StarrySkyLamp_MaxCurrent;//todo
        break;

    default:
        value = StarrySkyLampOutput_Night_MA/DaytimeLampOutput_MA*StarrySkyLamp_MaxCurrent;//% 26ma
        break;
    }

    return value;
}

#define EPSILON 0.0001
bool IsFloatEqual(float f1, float f2)
{
	bool op1 = ((f1 - f2) > -EPSILON);
	bool op2 = ((f1 - f2) < EPSILON);
    return op1 && op2;
}

//==============================Sleep/Weak Up==============================
bool IsSystemRequestSleep()
{
    return g_Widget->itsWeakupState->currentIndex();
}

void SystemCtrl_StartSleep()
{

}


void SystemCtrl_StartWeakup()
{

}


//=========================== Daytime Lamp ================================
void InitDayTimeLamp()
{
}

void DeinitDayTimeLamp()
{
}

OnOffFlag Get_CANSIG_DaytimeLampOnCmd()
{
    return (OnOffFlag)g_Widget->itsDaytimeLampOnCmd->currentIndex();
}

bool IsDRL_LED_Issue()
{
    return g_Widget->itsDRL_LED_Issue->currentIndex();
}

bool IsDayTimeLampLcuUartcanCommunicationIssue()
{
    return g_Widget->itsDayTimeLampLcuUartcanCommunicationIssue->currentIndex();
}

void Set_CANSIG_FLDaytimeLampOnSt(OnOffFlag value)
{
    g_Widget->itsFLDaytimeLampOnSt->setText(g_Widget->createOutSigalName(value));
}

void Set_CANSIG_FLDaytimeLampFlt(DiagFlag value)
{
    g_Widget->itsFLDaytimeLampFlt->setText(g_Widget->createOutFaultName(value));
}

//=========================== Posn(Position) Lamp ================================

OnOffFlag Get_CANSIG_FLPosnLampOnCmd()
{
    return (OnOffFlag)g_Widget->itsFLPosnLampOnCmd->currentIndex();
}

FLPosnLampBriSetFlag Get_CANSIG_FLPosnLampBriSet()
{
    return (FLPosnLampBriSetFlag)g_Widget->itsFLPosnLampBriSet->currentIndex();
}

float LocalQuery_TurnLampBrightness()
{
    return 100.0f;
}

bool IsPO_SW_OutputIssue()
{
    return g_Widget->createDiagValueFromComboBox(g_Widget->itsPW_SW_OutputIssue);
}

void Set_CANSIG_LeFrntPosnLampOnSt(OnOffFlag value)
{
    g_Widget->itsLeFrntPosnLampOnSt->setText(g_Widget->createOutSigalName(value));
}

void Set_CANSIG_LeFrntPosnLampBri(float value)
{
    if(IsFloatEqual(value, PosnLampOutput_Night_MA/DaytimeLampOutput_MA*DaytimeLampPwm_MaxCurrent))
    {
        g_Widget->itsLeFrntPosnLampBri->setText("0x1:Night");
    }
    else if(IsFloatEqual(value, PosnLampOutput_DAY1_MA/DaytimeLampOutput_MA*DaytimeLampPwm_MaxCurrent))
    {
        g_Widget->itsLeFrntPosnLampBri->setText("0x2:Daytime1");
    }
    else if(IsFloatEqual(value, PosnLampOutput_DAY2_MA/DaytimeLampOutput_MA*DaytimeLampPwm_MaxCurrent))
    {
        g_Widget->itsLeFrntPosnLampBri->setText("0x3:Daytime2");
    }
    else if(IsFloatEqual(value, PosnLampOutput_Initial_MA/DaytimeLampOutput_MA*DaytimeLampPwm_MaxCurrent))
    {
        g_Widget->itsLeFrntPosnLampBri->setText("0x0:Initial");
    }
    else
    {
        g_Widget->itsLeFrntPosnLampBri->setText("0x7:Invaild");
    }
}

void Set_CANSIG_LeFrntPosnLampFlt(DiagFlag value)
{
    switch(value)
    {
    case 0x00: g_Widget->itsLeFrntPosnLampFlt->setText("0x0：Initial");      break;
        case 0x01: g_Widget->itsLeFrntPosnLampFlt->setText("0x1：No Fault");   break;
        case 0x02: g_Widget->itsLeFrntPosnLampFlt->setText("0x2：Fault");   break;
        case 0x03: g_Widget->itsLeFrntPosnLampFlt->setText("0x3：Invalid");      break;
            default:   g_Widget->itsLeFrntPosnLampFlt->setText("Undefine");     break;
    }
}

static float DaytimeAndPosnPWM = 0.0f;
void Set_LampCtrl_DaytimeAndPosnLampsStatus(uint32_t change_mask, uint32_t onoff_mask, float pwm)
{
    uint32_t index = 0x01;
    DaytimeAndPosnPWM = pwm;
    float proportion = 255*pwm/DaytimeLampPwm_MaxCurrent;
    for(int i = 0; i < 32; i++)
    {
        if((index << i) & change_mask)
        {
            if((index << i) & onoff_mask)
            {
                g_Widget->Lamp_Pwm_Ctrl(g_Widget->itsDatTimeAndPosLamps[i], (uint8_t)proportion);
            }
            else
            {
                g_Widget->Lamp_Pwm_Ctrl(g_Widget->itsDatTimeAndPosLamps[i], 0);
            }
        }
    }
}

OnOffFlag LocalQuery_LeFrntPosnLampOnSt()
{
    return OnOff_Initial;
}

float LocalQuery_LeFrntDaytimePosnLampBri()
{
    return DaytimeAndPosnPWM;
}

bool IsPosnDevBusy()
{
    return false;
}

void Set_LampCtrl_StarrySkyLampsStatus(uint32_t change_mask, uint32_t onoff_mask, float pwms)
{
    uint32_t index = 0x01;
    float proportion = 255*pwms/DaytimeLampPwm_MaxCurrent;
    for(int i = 0; i < 10; i++)
    {
        if((index << i) & change_mask)
        {
            if((index << i) & onoff_mask)
            {
                g_Widget->Lamp_Pwm_Ctrl(g_Widget->itsStarrySkyLamps[i], (uint8_t)proportion);
            }
            else
            {
                g_Widget->Lamp_Pwm_Ctrl(g_Widget->itsStarrySkyLamps[i], 0);
            }
        }
    }
}

OnOffFlag LocalQuery_StarrySkyLampsOnOffSt()
{
    return OnOff_Initial;
}

bool IsStarrySkyLampsDevBusy()
{
    return false;
}

void Set_LampCtrl_StarrySkyAndPo2Lamp_Enable(bool value)
{

}

//=========================== DLP Module ================================
void InitDlpModule()
{
}

void DeinitDlpModule()
{
}

uint8_t Get_CANSIG_OdpLedBrtnsAdjstReq()
{
    return g_Widget->getTextInputAsU16(g_Widget->its_DO_S32K_SL3409_PWM);
}

ProjectionAngle  Get_CANSIG_PubProjectionAngleAdjstReq()
{
    return (ProjectionAngle)g_Widget->itsPubProjectionAngleAdjstReq->currentIndex();
}

bool Is_IO_LM3409_EN()
{
    return g_Widget->createIOValueFromComboBox(g_Widget->itsIO_LM3409_EN);
}

void Set_DLP_LED1(bool value)
{
}

void Set_DLP_LED2(bool value)
{
}

void Set_DO_S32K_SL3409_PWM(uint8_t value)
{
    value = value * 255 / 99; //色调变化在0-255
    g_Widget->Lamp_Pwm_Ctrl(g_Widget->itsDlpModuls[0], value);
}

void Set_LM3409_EN(bool value)
{
}

void Set_MotorCtrl_ProjectionAngle(float angle)
{
    std::stringstream sstr;
    sstr << angle << "o";
    g_Widget->its_motor_Angle->setText(sstr.str().c_str());
}


//=========================== Hibeam Lamp ================================
void InitHiBeam()
{
}

void DeinitHiBeam()
{
}

OnOffFlag Get_CANSIG_HiBeamOnCmd()
{
    return (OnOffFlag)g_Widget->itsHiBeamOnCmd->currentIndex();
}

float LocalQuery_HibeamBrightness()
{
    return 100.0f;
}

//OnOffFlag Get_CANSIG_AdpvHiBeamFctOnCmd()
//{
//    return g_Widget->createDiagValueFromComboBox(g_Widget->itsHiBeamBuckChannelIssue);
//}

bool IsHiBeamBuckChannelIssue()
{
    return g_Widget->createDiagValueFromComboBox(g_Widget->itsHiBeamBuckChannelIssue);
}

bool IsHiBeamLedDevIssue()
{
    return g_Widget->createDiagValueFromComboBox(g_Widget->itsHiBeamLedDevIssue);
}

bool IsHiBeamBuckOutputIssue()
{
    return g_Widget->createDiagValueFromComboBox(g_Widget->itsHiBeamBuckOutputIssue);
}

void Set_CANSIG_LeHiBeamOnSt(OnOffFlag value)
{
    g_Widget->itsLeHiBeamOnSt->setText(g_Widget->createOutSigalName(value));
}

void Set_CANSIG_LeHiBeamFlt(DiagFlag value)
{
    g_Widget->itsLeHiBeamFlt->setText(g_Widget->createOutFaultName(value));
}

void Set_Lamp_Ctrl_HiBeamPwm(float pwm)
{

}

OnOffFlag hibeamSt = OnOff_Initial;
void Set_HiBeam_OnOffState(bool value)
{
    hibeamSt = value ? OnOff_On : OnOff_Off;
    g_Widget->Lamp_Status_Ctrl(g_Widget->itsHiBeam[0], value);
}

OnOffFlag LocalQuery_LeHiBeamOnSt()
{
    return hibeamSt;
}

bool IsHiBeamDevBusy()
{
    return false;
}

//=========================== Ribbon ================================
void InitLampLanguage()
{
}

void DeinitLampLanguage()
{
}

UsageModeFlag Get_CANSIG_UsageMode()
{
    return (UsageModeFlag)g_Widget->itsUsageMode->currentIndex();
}

RibbonCtrlCmd Get_CANSIG_FrntRibbonLampEffectCtrlCmd()
{
    return (RibbonCtrlCmd)g_Widget->itsFrntRibbonLampEffectCtrlCmd->currentIndex();
}

RibbonEffectSel Get_CANSIG_FrntRibbonLampEffectSel()
{
    return (RibbonEffectSel)g_Widget->itsFrntRibbonLampEffectSel->currentIndex();
}

RibbonEffectMod Get_CANSIG_FrntRibbonLampEffectModSet()
{
    return (RibbonEffectMod)g_Widget->itsFrntRibbonLampEffectModSet->currentIndex();
}

RibbonCtrlCmd Get_CANSIG_LoBeamEffectCtrlCmd()
{
    return (RibbonCtrlCmd)g_Widget->itsLoBeamEffectCtrlCmd->currentIndex();
}

RibbonEffectSel Get_CANSIG_LoBeamEffectSel()
{
    return (RibbonEffectSel)g_Widget->itsLoBeamEffectSel->currentIndex();
}

RibbonEffectMod Get_CANSIG_LoBeamEffectModSet()
{
    return RibbonEffectMod_Initial;
}

static std::string RibbonEffectShowSt2String(RibbonEffectShowSt value)
{
    switch(value)
    {
    case RibbonEffectShow_OFF: return "0x00:Off";
    case RibbonEffectShow_Running: return "0x01:Running";
    case RibbonEffectShow_Pause: return "0x02:Pause";
    case RibbonEffectShow_Hold: return "0x03:Hold";
    case RibbonEffectShow_Reserved_4: return "0x04:Reserved";
    case RibbonEffectShow_Reserved_5: return "0x05:Reserved";
    case RibbonEffectShow_Reserved_6: return "0x06:Reserved";
    default: return "0x07:Invaild";
    }
}

static std::string RibbonLampEffectSt2String(RibbonEffectSel value)
{
    switch(value)
    {
    case RibbonEffectSel_Initial: return "0x00:Initial";
    case RibbonEffect_Effect_1: return "0x01:Effect_1";
    case RibbonEffect_Effect_2: return "0x02:Effect_2";
    case RibbonEffect_Effect_3: return "0x03:Effect_3";
    case RibbonEffect_Effect_4: return "0x04:Effect_4";
    case RibbonEffect_Effect_5: return "0x05:Effect_5";
    case RibbonEffect_Effect_6: return "0x06:Effect_6";
    case RibbonEffect_Effect_7: return "0x07:Effect_7";
    case RibbonEffect_Effect_8: return "0x08:Effect_8";
    case RibbonEffect_Effect_9: return "0x09:Effect_9";
    case RibbonEffect_Effect_a: return "0x0a:Effect_a";
    case RibbonEffect_Effect_b: return "0x0b:Effect_b";
    case RibbonEffect_Effect_c: return "0x0c:Effect_c";
    case RibbonEffect_Effect_d: return "0x0d:Effect_d";
    case RibbonEffect_Effect_e: return "0x0e:Effect_e";
    case RibbonEffect_Effect_f: return "0x0f:Effect_f";
    default: return "Undefine";
    }
}

void Set_CANSIG_FrntRibbonLampEffectShowSt(RibbonEffectShowSt value)
{
    g_Widget->itsFrntRibbonLampEffectShowSt->setText(RibbonEffectShowSt2String(value).c_str());
}

void Set_CANSIG_FrntRibbonLampEffectSt(RibbonEffectSel value)
{
    g_Widget->itsFrntRibbonLampEffectSt->setText(RibbonLampEffectSt2String(value).c_str());
}

void Set_CANSIG_LoBeamEffectShowSt(RibbonEffectShowSt value)
{
    g_Widget->itsLoBeamEffectShowSt->setText(RibbonEffectShowSt2String(value).c_str());
}

void Set_CANSIG_LoBeamEffectSt(RibbonEffectSel value)
{
    g_Widget->itsLoBeamEffectSt->setText(RibbonLampEffectSt2String(value).c_str());
}


//=========================== LeTurn(Left turn) Lamp ================================
void InitLeftFrontTurnLamp()
{
}

void DeinitLeftFrontTurnLamp()
{
}

bool Is_TL_EN()
{
    return g_Widget->createIOValueFromComboBox(g_Widget->itsTL_EN);
}

bool Is_TL_Flow()
{
    return g_Widget->createIOValueFromComboBox(g_Widget->itsTL_Flow);
}

TurnLampOccupyStsFlag Get_CANSIG_TurnLampOccupySts()
{
    return (TurnLampOccupyStsFlag)g_Widget->itsTurnLampOccupySts->currentIndex();
}

void Get_UARTCAN_LeFrntTurnLampFlowEffect(uint8_t* time, uint8_t* direction, uint8_t* performance)
{
}

bool IsLeFrntTurnLampLcuUartcanCommunicationIssue()
{
    return g_Widget->createDiagValueFromComboBox(g_Widget->itsLeFrntTurnLampLcuUartcanCommunicationIssue);
}

bool IsTL_SW_OutputIssue()
{
    return g_Widget->createDiagValueFromComboBox(g_Widget->itsTL_SW_OutputIssue);
}

bool IsLeFrntTurnLampLedIssue()
{
    return g_Widget->createDiagValueFromComboBox(g_Widget->itsLeFrntTurnLampLedIssue);
}

void Set_CANSIG_LeFrntTurnLampOnSt(OnOffFlag value)
{
    g_Widget->itsLeFrntTurnLampOnSt->setText(g_Widget->createOutSigalName(value));
}

void Set_CANSIG_LeFrntTurnLampFlt(DiagFlag value)
{
    g_Widget->itsLeFrntTurnLampFlt->setText(g_Widget->createOutFaultName(value));
}

void Set_LeFrntTurnLamp_OnOffState(bool value)
{
    g_Widget->itsLeftFrontTurnLampSwitch = value;
}

OnOffFlag leturnSt = OnOff_Initial;
void Set_LampCtrl_TurnLampsStatus(uint32_t change_mask, uint32_t onoff_mask, float pwms)
{
    leturnSt = onoff_mask > 0 ? OnOff_On : OnOff_Off;
    uint32_t index = 0x01;
    float proportion = 255*pwms;
    for(int i = 0; i < 32; i++)
    {
        if((index << i) & change_mask)
        {
            if((index << i) & onoff_mask)
            {
                g_Widget->Lamp_Pwm_Ctrl(g_Widget->itsLeftFrontTurnLamps[i], (uint8_t)proportion);
            }
            else
            {
                g_Widget->Lamp_Pwm_Ctrl(g_Widget->itsLeftFrontTurnLamps[i], 0);
            }
        }
    }
}

OnOffFlag LocalQuery_LeFrntTurnLampOnSt()
{
    return leturnSt;
}

bool IsLeFrntTurnLampDevBusy()
{
    return false;
}

//=========================== LoBeam ================================
void InitLoBeam()
{
}

void DeinitLoBeam()
{
}

OnOffFlag Get_CANSIG_LoBeamOnCmd()
{
    return (OnOffFlag)g_Widget->itsLoBeamOnCmd->currentIndex();
}

bool IsLoBeamBuckChannelIssue()
{
    return g_Widget->createDiagValueFromComboBox(g_Widget->itsLoBeamBuckChannelIssue);
}

bool IsLoBeamLedDevIssue()
{
    return g_Widget->createDiagValueFromComboBox(g_Widget->itsLoBeamLedDevIssue);
}

bool IsLoBeamBuckOutputIssue()
{
    return g_Widget->createDiagValueFromComboBox(g_Widget->itsLoBeamBuckOutputIssue);
}

bool IsLoBeamPowerSupplyIssue()
{
    return g_Widget->createDiagValueFromComboBox(g_Widget->itsLoBeamPowerSupplyIssue);
}

float LocalQuery_LobeamBrightness()
{
    return 100.0f;
}

void Set_CANSIG_LeLoBeamOnSt(OnOffFlag value)
{
    g_Widget->itsLeLoBeamOnSt->setText(g_Widget->createOutSigalName(value));
}

void Set_CANSIG_LeLoBeamFlt(DiagFlag value)
{
    g_Widget->itsLeLoBeamFlt->setText(g_Widget->createOutFaultName(value));
}

OnOffFlag LoBeamSt = OnOff_Initial;
void Set_LoBeam_OnOffState(bool value)
{
    LoBeamSt = value ? OnOff_On : OnOff_Off;
    g_Widget->isLobeamEnable = value;
}

void Set_Lamp_Ctrl_LobeamPwm(float pwm)
{
    if(g_Widget->isLobeamEnable)
    {
        g_Widget->Lamp_Pwm_Ctrl(g_Widget->itsLoBeam[0], 255*pwm/100);
    }
    else
    {
        g_Widget->Lamp_Pwm_Ctrl(g_Widget->itsLoBeam[0], 0);
    }
}

void Set_LampCtrl_SwitchBetweenCornerLampAndLoBeam(bool value)
{
}

OnOffFlag LocalQuery_LeLoBeamOnSt()
{
    return LoBeamSt;
}

DiagFlag LocalQuery_LeLoBeamFlt()
{
    return Diag_Initial;
}

void Set_PO2_OnOffState(bool value)
{
    g_Widget->Lamp_Status_Ctrl(g_Widget->itsPO2_LED[0], !value);
}

OnOffFlag LocalQuery_Po2OnOffSt()
{
    return OnOff_Initial;
}

bool IsLoBeamDevBusy()
{
    return false;
}

//=========================== Corner Lamp ================================
void InitCornerLamp()
{
}

void DeinitCornerLamp()
{
}

AFSEnaFlag Get_CANSIG_AFSEna()
{
    return (AFSEnaFlag)g_Widget->itsAFSEna->currentIndex();
}

float Get_CANSIG_VehicleSpeed()
{
    return g_Widget->getTextInputAsU16(g_Widget->its_VehicleSpeed);
}

float Get_CANSIG_SteeringAngle()
{
    return g_Widget->getTextInputAsInt16(g_Widget->its_SteeringWheelAngle);
}

float LocalQuery_CornerLampBrightness()
{
    return 100.0f;
}

bool Is_CL_SW_SwitchIssue()
{
    return g_Widget->createDiagValueFromComboBox(g_Widget->itsCL_SW_SwitchIssue);
}

void Set_CANSIG_LCU_FL_FLCornerLampOnSt(OnOffFlag value)
{
    g_Widget->itsLCU_FL_FLCornerLampOnSt->setText(g_Widget->createOutSigalName(value));
}

void Set_CANSIG_LCU_FL_FLCornerLampFlt(DiagFlag value)
{
    g_Widget->itsLCU_FL_FLCornerLampOnSt->setText(g_Widget->createOutFaultName(value));
}

void Set_Corner_OnOffState(bool value)
{
    g_Widget->Lamp_Status_Ctrl(g_Widget->itsCornerLamp[0], value);
}

void Set_Corner_brightness(float value)
{

}

void Set_CL_SW(uint8_t value)
{
}

OnOffFlag LocalQuery_FL_FLCornerLampOnSt()
{
    return OnOff_Initial;
}

void Set_FanCtrl_OnOffState(bool value)
{

}

float LocalQuery_TurnLampBrightness_Voltage(void)
{
    return 100.0f;
}

float LocalQuery_TurnLampBrightness_Temperature(void)
{
    return 100.0f;
}

float LocalQuery_StarrySkyLampBrightness_Voltage(void)
{
    return 100.0f;
}

float LocalQuery_StarrySkyLampBrightness_Temperature(void)
{
    return 100.0f;
}

float LocalQuery_HibeamBrightness_Voltage()
{   
    return 100.0f;
}

float LocalQuery_HibeamBrightness_Temperature()
{
    return 100.0f;
}

float LocalQuery_LobeamBrightness_Voltage()
{
    return 100.0f;
}

float LocalQuery_LobeamBrightness_Temperature()
{
    return 100.0f;
}

float LocalQuery_CornerLampBrightness_Voltage()
{
    return 100.0f;
}

float LocalQuery_CornerLampBrightness_Temperature()
{
    return 100.0f;
}

bool IsDaytimeAndPosnNTCShortCircuit()
{
    return false;
}

bool IsDaytimeAndPosnNTCOpenCircuit()
{
    return false;
}

bool IsStarrySkyNTCShortCircuit()
{
    return false;
}

bool IsStarrySkyNTCOpenCircuit()
{
    return false;
}

bool IsHiBeamNTCShortCircuit()
{
    return false;
}

bool IsHiBeamNTCOpenCircuit()
{
    return false;
}

bool IsCornerLampNTCShortCircuit()
{
    return false;
}

bool IsCornerLampNTCOpenCircuit()
{
    return false;
}

bool IsLoBeamNTCOpenCircuit()
{
    return false;
}

bool IsLoBeamNTCShortCircuit()
{
    return false;
}
